package com.hjc.demo.netty.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

import javax.swing.plaf.FontUIResource;
import java.net.SocketAddress;

public class NettyServer {

    static EventLoopGroup boss = new NioEventLoopGroup();
    static EventLoopGroup worker = new NioEventLoopGroup();

    private static ServerBootstrap setUp() {

        return new ServerBootstrap().group(boss, worker)
                .channel(NioServerSocketChannel.class)
                .option(ChannelOption.SO_BACKLOG, 128) // tcp最大缓存链接个数
                .childOption(ChannelOption.SO_KEEPALIVE, true) //保持连接
                .handler(new LoggingHandler(LogLevel.INFO)) // 打印日志级别
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {

                        // marshalling 序列化对象的解码
//                      socketChannel.pipeline().addLast(MarshallingCodefactory.buildDecoder());
                        // marshalling 序列化对象的编码
//                      socketChannel.pipeline().addLast(MarshallingCodefactory.buildEncoder());
                        // 网络超时时间
//                      socketChannel.pipeline().addLast(new ReadTimeoutHandler(5));
                        socketChannel.pipeline().addLast(new ChannelOutboundHandlerAdapter(){
                            @Override
                            public void bind(ChannelHandlerContext ctx, SocketAddress localAddress, ChannelPromise promise) throws Exception {
                                System.out.println("bind...");
                                super.bind(ctx, localAddress, promise);
                            }

                            @Override
                            public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) throws Exception {
                                System.out.println("connect...");
                                super.connect(ctx, remoteAddress, localAddress, promise);
                            }

                            @Override
                            public void disconnect(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
                                System.out.println("disconnect...");
                                super.disconnect(ctx, promise);
                            }

                            @Override
                            public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
                                System.out.println("close...");
                                super.close(ctx, promise);
                            }

                            @Override
                            public void deregister(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
                                System.out.println("deregister...");
                                super.deregister(ctx, promise);
                            }

                            @Override
                            public void read(ChannelHandlerContext ctx) throws Exception {
                                System.out.println("read...");
                                super.read(ctx);
                            }

                            @Override
                            public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
                                System.out.println("write...");
                                super.write(ctx, msg, promise);
                            }

                            @Override
                            public void flush(ChannelHandlerContext ctx) throws Exception {
                                System.out.println("flush...");
                                super.flush(ctx);
                            }
                        });
                        // 处理接收到的请求
                        socketChannel.pipeline().addLast(new ServerHandler()); // 这里相当于过滤器，可以配置多个
                    }
                });

    }

    public static void start(int port) {
        ServerBootstrap bootstrap = setUp();
        try {
            ChannelFuture future = bootstrap.bind(port).sync();
            future.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            boss.shutdownGracefully();
            worker.shutdownGracefully();
        }
    }
}
